#from sklearn.cluster import MeanShift
import numpy
from matplotlib import pyplot
#classifer=MeanShift(bandwidth=3)
data=numpy.loadtxt('./testSet.txt')
# classifer.fit(data)
# labels = classifer.labels_
# centroids = classifer.cluster_centers_
# for i in range(4):
#     cluster_data = data[labels == i]
#     pyplot.scatter(cluster_data[:, 0], cluster_data[:, 1])
# pyplot.show()
#自行原理实现
#1.先选择bandwidth作为高维球的半径，还要赋予每个点一个字典，记录被每一类簇访问的频率
#2.如果两次均值漂移后中心点的距离小于一个值，则将这两类合并为一类
#3.为每一个设置一个是否被访问过的标签，用0，1表示，0表示未被访问，1表示已被访问
#4.一个数组记录中心点，中心的数量可变，list对象最好
length=data.shape[0]
band_width=3
data=numpy.hstack((data,numpy.zeros((length,1))))
#定义记录
dic=numpy.zeros((length,100))
i=0
centre_point_list=[]
while not numpy.all(data[:,-1]):
    #随机选择未被访问的点作为中心点
    sample=data[data[:,-1]==0]
    l=sample.shape[0]
    centre_point=sample[numpy.random.choice(l)][0:-1]
    vector_length = numpy.inf
    while vector_length>00.1:
        #求所有点与该点的距离
        distance=numpy.sqrt(numpy.sum((data[:,0:-1]-centre_point)**2,axis=1))
        #标记被访问点
        index=distance<=band_width
        data[index,-1]=1#将这些点设置为已经被访问
        dic[index,i]+=1#类别的访问次数进行计数
        #计算向量
        vector=numpy.sum(data[index,0:-1]-centre_point,axis=0)/numpy.sum(index)
        vector_length=numpy.linalg.norm(vector)
        #移动中心点
        centre_point=centre_point+vector
    centre_point_list.append(list(centre_point))
    # 计算该中心点与其他中心点的距离,如果有一个中心点与该中心点的距离相近，则把两类归为一类
    if i>0:
        nar=numpy.array(centre_point_list)
        diff=numpy.sum((nar[0:-1]-nar[-1])**2,axis=1)
        idx=numpy.argmin(diff)
        if diff[idx]<=0.001:
            dic[:,i]=dic[:,i]+dic[:,idx]
            dic[:,i]=0
        else:
            i=i+1
    else:
        i=i+1
cls=numpy.argmax(dic,axis=1)
pyplot.scatter(data[:,0],data[:,1],c=cls)
pyplot.show()
